home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / ax25hdr.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  3KB  |  111 lines

  1. /* @(#) $Header: ax25hdr.c,v 1.3 92/05/14 13:19:45 deyke Exp $ */
  2.  
  3. /* AX25 header conversion routines
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9.  
  10. /* Convert a host-format AX.25 header into a mbuf ready for transmission */
  11. struct mbuf *
  12. htonax25(hdr,bp)
  13. register struct ax25 *hdr;
  14. struct mbuf *bp;
  15. {
  16.     register char *cp;
  17.     register int16 i;
  18.  
  19.     if(hdr == (struct ax25 *)NULL || hdr->ndigis > MAXDIGIS)
  20.         return NULLBUF;
  21.  
  22.     /* Allocate space for return buffer */
  23.     i = AXALEN * (2 + hdr->ndigis);
  24.     bp = pushdown(bp,i);
  25.  
  26.     /* Now convert */
  27.     cp = bp->data;          /* cp -> dest field */
  28.  
  29.     /* Generate destination field */
  30.     memcpy(cp,hdr->dest,AXALEN);
  31.     if(hdr->cmdrsp == LAPB_COMMAND)
  32.         cp[ALEN] |= C;  /* Command frame sets C bit in dest */
  33.     else
  34.         cp[ALEN] &= ~C;
  35.     cp[ALEN] &= ~E; /* Dest E-bit is always off */
  36.  
  37.     cp += AXALEN;           /* cp -> source field */
  38.  
  39.     /* Generate source field */
  40.     memcpy(cp,hdr->source,AXALEN);
  41.     if(hdr->cmdrsp == LAPB_RESPONSE)
  42.         cp[ALEN] |= C;
  43.     else
  44.         cp[ALEN] &= ~C;
  45.     /* Set E bit on source address if no digis */
  46.     if(hdr->ndigis == 0){
  47.         cp[ALEN] |= E;
  48.         return bp;
  49.     } else
  50.         cp[ALEN] &= ~E;
  51.  
  52.     cp += AXALEN;           /* cp -> first digi field */
  53.  
  54.     /* All but last digi get copied with E bit off */
  55.     for(i=0; i < hdr->ndigis; i++){
  56.         memcpy(cp,hdr->digis[i],AXALEN);
  57.         if(i < hdr->ndigis - 1)
  58.             cp[ALEN] &= ~E;
  59.         else
  60.             cp[ALEN] |= E;  /* Last digipeater has E bit set */
  61.         if(i < hdr->nextdigi)
  62.             cp[ALEN] |= REPEATED;
  63.         else
  64.             cp[ALEN] &= ~REPEATED;
  65.         cp += AXALEN;           /* cp -> next digi field */
  66.     }
  67.     return bp;
  68. }
  69. /* Convert a network-format AX.25 header into a host format structure
  70.  * Return -1 if error, number of addresses if OK
  71.  */
  72. int
  73. ntohax25(hdr,bpp)
  74. register struct ax25 *hdr;      /* Output structure */
  75. struct mbuf **bpp;
  76. {
  77.     register char *axp;
  78.  
  79.     if(pullup(bpp,hdr->dest,AXALEN) < AXALEN)
  80.         return -1;
  81.  
  82.     if(pullup(bpp,hdr->source,AXALEN) < AXALEN)
  83.         return -1;
  84.  
  85.     /* Process C bits to get command/response indication */
  86.     if((hdr->source[ALEN] & C) == (hdr->dest[ALEN] & C))
  87.         hdr->cmdrsp = LAPB_UNKNOWN;
  88.     else if(hdr->source[ALEN] & C)
  89.         hdr->cmdrsp = LAPB_RESPONSE;
  90.     else
  91.         hdr->cmdrsp = LAPB_COMMAND;
  92.  
  93.     hdr->ndigis = 0;
  94.     hdr->nextdigi = 0;
  95.     if(hdr->source[ALEN] & E)
  96.         return 2;       /* No digis */
  97.  
  98.     /* Count and process the digipeaters */
  99.     axp = hdr->digis[0];
  100.     while(hdr->ndigis < MAXDIGIS && pullup(bpp,axp,AXALEN) == AXALEN){
  101.         hdr->ndigis++;
  102.         if(axp[ALEN] & REPEATED)
  103.             hdr->nextdigi++;
  104.         if(axp[ALEN] & E)       /* Last one */
  105.             return hdr->ndigis + 2;
  106.         axp += AXALEN;
  107.     }
  108.     return -1;      /* Too many digis */
  109. }
  110.  
  111.